<template>
  <div style="width: 100%; height: 100%; display: flex">
    <el-tabs class="config-panel" type="border-card">
      <el-tab-pane :label="translate('常规')">
        <el-descriptions :column="2" border>
          <el-descriptions-item :label="translate('配置名称')" :span="2">
            <el-input :class="chatConf.name ? '' : 'danger__input'" v-model="chatConf.name" :placeholder="translate('配置名称')"/>
          </el-descriptions-item>
          <el-descriptions-item :label="translate('直播平台')">
            <el-select v-model="chatConf.platform" style="width: 160px">
              <el-option v-for="item in platformList" :key="item.id" :label="item.name" :value="item.id"/>
            </el-select>
          </el-descriptions-item>
          <el-descriptions-item :label="translate('房间号')">
            <el-input :class="chatConf.room ? '' : 'danger__input'" v-model="chatConf.room" :placeholder="translate('直播间房间号')"/>
          </el-descriptions-item>
          <el-descriptions-item :label="translate('显示欢迎')">
            <el-switch v-model="chatConf.display.welcome" inline-prompt active-text="Y" inactive-text="N"/>
          </el-descriptions-item>
          <el-descriptions-item :label="translate('显示弹幕')">
            <el-switch v-model="chatConf.display.chat" inline-prompt active-text="Y" inactive-text="N"/>
          </el-descriptions-item>
          <el-descriptions-item :label="translate('显示超级弹幕')">
            <el-switch v-model="chatConf.display.sc" inline-prompt active-text="Y" inactive-text="N"/>
          </el-descriptions-item>
          <el-descriptions-item :label="translate('显示礼物')">
            <el-switch v-model="chatConf.display.gift" inline-prompt active-text="Y" inactive-text="N"/>
          </el-descriptions-item>
          <el-descriptions-item :label="translate('操作')" :span="2">
            <el-button type="danger" @click="handleOpenLive">{{ translate('跳转直播姬') }}</el-button>
            <el-button type="success" @click="handleConfDialog('拉取')">{{ translate('拉取配置') }}</el-button>
            <el-button type="primary" @click="handleConfDialog('同步')">{{ translate('同步配置') }}</el-button>
          </el-descriptions-item>
        </el-descriptions>
        <div style="flex: 1; margin-top: 1rem; overflow: hidden">
          <Codemirror ref="mirrorRef" v-model="chatConf.style" style="height: 100%" :extensions="[css(), oneDark]" autofocus/>
        </div>
      </el-tab-pane>

      <el-tab-pane :label="translate('屏蔽')">
        <el-descriptions :column="2" border>
          <el-descriptions-item :span="2" width="200">
            <template #label>
              <span style="margin-right: 1rem">{{ translate('屏蔽关键词') }}</span>
              <el-button size="small" type="primary" @click="addBlock = {flag: true, title: '添加关键字'}">
                {{ translate('新增') }}
              </el-button>
            </template>
            <span v-if="!chatConf.shield.Keyword.length" style="color: var(--z-note-color)">{{ translate('暂无相关信息') }}</span>
            <el-tag v-else v-for="(item, index) in chatConf.shield.Keyword" closable style="margin: .2rem"
                    @close="chatConf.shield.Keyword.splice(index, 1)">
              {{ item }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item :span="2">
            <template #label>
              <span style="margin-right: 1rem">{{ translate('屏蔽用户') }}</span>
              <el-button size="small" type="primary" @click="addBlock = {flag: true, title: '添加用户'}">
                {{ translate('新增') }}
              </el-button>
            </template>
            <span v-if="!chatConf.shield.user.length" style="color: var(--z-note-color)">{{ translate('暂无相关信息') }}</span>
            <el-tag v-else v-for="(item, index) in chatConf.shield.user" closable style="margin: .2rem"
                    @close="chatConf.shield.user.splice(index, 1)">
              {{ item }}
            </el-tag>
          </el-descriptions-item>
        </el-descriptions>
      </el-tab-pane>
    </el-tabs>

    <el-card class="fake-panel">
      <LiveRoom :list="list" :config="chatConf"/>
      <div class="btn-wrap">
        <span style="font-weight: bold; color: var(--z-theme-light-color); padding-right: .4rem">
          {{ translate('开启滚动') }}
        </span>
        <el-switch v-model="randomState" inline-prompt active-text="Y" inactive-text="N" @change="randomChat"/>
      </div>
    </el-card>

    <el-dialog v-model="addBlock.flag" :title="translate(addBlock.title)" width="320px">
      <el-input v-model="addBlock.data" :placeholder="translate('屏蔽的内容')"/>
      <template #footer>
        <el-button @click="addBlock = {}">{{ translate('关闭') }}</el-button>
        <el-button type="primary" @click="handleAddBlock">{{ translate('确认') }}</el-button>
      </template>
    </el-dialog>
    <el-dialog v-model="confDialog.flag" :title="translate(confDialog.title + '配置')">
      <el-table ref="confTableRef" :data="confDialog.list" border max-height="640px" style="width: 100%">
        <el-table-column type="selection"/>
        <el-table-column prop="id" label="ID" width="100"/>
        <el-table-column show-overflow-tooltip prop="name" :label="translate('配置名称')" min-width="100"/>
        <el-table-column show-overflow-tooltip prop="platform" :label="translate('直播平台')" min-width="100">
          <template #default="{row}">
            {{ platformList.find(o => o.id === row.platform)?.name ?? translate('平台不存在') }}
          </template>
        </el-table-column>
        <el-table-column show-overflow-tooltip prop="room" :label="translate('房间号')" min-width="100"/>
        <el-table-column fixed="right" width="100">
          <template #header>
            <el-button v-if="confDialog.title === '拉取'" type="danger" size="small" @click="handleOpConf('删除')">
              {{ translate('删除') }}
            </el-button>
            <el-button v-else type="primary" size="small" @click="handleOpConf('新增')">
              {{ translate('新增') }}
            </el-button>
          </template>
          <template #default="{row}">
            <el-button type="success" size="small" @click="handleOpConf(confDialog.title, row)">
              {{ translate(confDialog.title) }}
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-dialog>
  </div>
</template>

<script setup>
import {inject, onActivated, onDeactivated, onMounted, ref} from 'vue'
import {css} from '@codemirror/lang-css'
import {oneDark} from '@codemirror/theme-one-dark'
import {Codemirror} from 'vue-codemirror'
import LiveRoom from '@/components/live-room'
import {cmdList, contentList, usernameList} from './fake-data'
import {ElMessage, ElMessageBox} from 'element-plus'

const layout = inject('layout') // 全局样式
const chatConf = ref({ // 全局配置
  id: null, // 唯一标识
  name: null, // 自定义名称，方便配置查找
  platform: 'BILI', // 平台
  room: null, // 房间CODE
  display: {
    welcome: true, // 进入房间
    chat: true, // 弹幕
    sc: true, // 超级弹幕
    gift: true, // 开通
  }, // 显示配置
  shield: {
    Keyword: [],
    user: [],
  }, // 屏蔽配置
  style: '', // 自定义样式
})
const translate = inject('translate') // 翻译
const addBlock = ref({}) // 添加屏蔽词弹框
const mirrorRef = ref() // style编辑器
const platformList = ref([]) // 当前支持的平台列表
const confDialog = ref({}) // 配置弹框
const confTableRef = ref() // 配置表格对象

const getRandomColor = inject('getRandomColor') // 随机颜色函数
const list = ref([]) // 弹幕数据列表
const randomState = ref(true) // 是否开启随机生成
let randomInterval = null

/**
 * 跳转直播姬
 */
function handleOpenLive() {
  if (!chatConf.value.id)
    return ElMessage.error(translate('配置未同步'))
  window.open('/#/live?confId=' + chatConf.value.id)
}

/**
 * 显示拉取 / 同步对话框
 */
function handleConfDialog(title) {
  layout.value.mainLoading = true
  request({
    url: '/conf/list',
    method: 'GET'
  }).then(res => {
    confDialog.value = {
      flag: true,
      title: title,
      list: res.data.data
    }
  }).finally(() => layout.value.mainLoading = false)
}

/**
 * 拉取 / 同步 配置内容
 */
function handleOpConf(type, row) {
  let format = JSON.parse(JSON.stringify(chatConf.value))
  if (row) format.id = row.id
  format.display = JSON.stringify(format.display)
  format.shield = JSON.stringify(format.shield)

  if (type === '拉取') {
    layout.value.mainLoading = true
    request({
      url: '/conf',
      method: 'GET',
      params: {id: row.id}
    }).then(res => {
      let data = res.data.data
      data.display = JSON.parse(data.display)
      data.shield = JSON.parse(data.shield)
      chatConf.value = data
      ElMessage.success('操作成功')
      confDialog.value = {}
    }).finally(() => layout.value.mainLoading = false)
  }
  else if (type === '删除') {
    let data = confTableRef.value.getSelectionRows().map(o => o.id)
    if (!data || !data.length) return ElMessage.error('选中数据为空')
    ElMessageBox.confirm(translate('确认提交'))
        .then(() => {
          layout.value.mainLoading = true
          const ids = confTableRef.value.getSelectionRows().map(o => o.id)
          return request({
            url: '/conf',
            method: 'DELETE',
            data: ids
          }).then(() => {
            ElMessage.success('操作成功')
            confDialog.value.list = confDialog.value['list']['filter'](o => ids.indexOf(o['id']) < 0)
          })
        }).catch(() => {}).finally(() => layout.value.mainLoading = false)
  }
  else if (type === '新增') {
    layout.value.mainLoading = true
    request({
      url: '/conf',
      method: 'POST',
      data: format
    }).then(res => {
      chatConf.value.id = res.data.data
      ElMessage.success('操作成功')
      confDialog.value = {}
    }).finally(() => layout.value.mainLoading = false)
  }
  else if (type === '同步') {
    ElMessageBox.confirm(translate('确认提交'))
        .then(() => {
          layout.value.mainLoading = true
          return request({
            url: '/conf',
            method: 'PUT',
            data: format
          }).then(() => {
            ElMessage.success('操作成功')
            confDialog.value = {}
          })
        }).catch(() => {}).finally(() => layout.value.mainLoading = false)
  }
}

/**
 * 添加屏蔽数据 【用户 / 关键字】
 */
function handleAddBlock() {
  let key = 'Keyword'
  if (addBlock.value['title'] === '添加用户') key = 'user'
  if (!addBlock.value['data'])
    return ElMessage.error(translate('屏蔽内容不能为空'))
  if (chatConf.value.shield[key].indexOf(addBlock.value['data']) >= 0)
    return ElMessage.error(translate('已存在该屏蔽信息'))
  chatConf.value.shield[key].push(addBlock.value['data'])
  addBlock.value = {}
}

/**
 * 随机对话内内容
 */
function randomChat() {
  !!randomInterval && clearInterval(randomInterval)
  if (!randomState.value) return

  function randomChat() {
    let cmd = cmdList[Math.floor(Math.random() * cmdList.length)]
    let giftId = ~~(Math.random() * 3) + 1
    return {
      key: Math.random(), // 随机key
      cmd: cmd, // 命令类型，根据类型调用不同的组件
      username: usernameList[Math.floor(Math.random() * usernameList.length)], // 用户名
      avatar: '/images/noface.gif', // 头像
      content: cmd === 'WELCOME' ? '进入了直播间' : contentList[Math.floor(Math.random() * contentList.length)], // 内容
      identities: [~~(Math.random() * 10)], // 身份标识
      time: '1970-01-01 00:00', // chat时间
      nameColor: getRandomColor(), // 用户名颜色
      contentColor: getRandomColor(), // 内容颜色
      bounty: Math.floor(Math.random() * 100 + 1), // 打赏金额
      giftId: cmd === 'GIFT' ? 0 : giftId, // 礼物ID
      gift: ['总督', '提督', '舰长'][giftId - 1], // 礼物
      num: Math.floor(Math.random() * 100 + 1), // 数量
    }
  }

  randomInterval = setInterval(() => {
    let msg = randomChat()
    if (chatConf.value.shield.user.includes(msg['username'])) return
    if (msg['cmd'] === 'WELCOME' && !chatConf.value.display.welcome) return
    if (msg['cmd'] === 'MSG' && !chatConf.value.display.chat) return
    if (msg['cmd'] === 'SC' && !chatConf.value.display.sc) return
    if (msg['cmd'] === 'VIP' && !chatConf.value.display.gift) return
    const copyList = JSON.parse(JSON.stringify(list.value))
    copyList.push(msg)
    if (copyList.length > 64)
      while (copyList.length > 32) copyList.shift()
    list.value = copyList
  }, 500)
}

/**
 * 保证style编辑框滚动条正确
 */
let scrollTop = 0
onMounted(() => {
  setTimeout(() => mirrorRef.value.$el.getElementsByClassName('cm-scroller')[0]
      .scrollTo({top: 0, behavior: 'smooth'}))
})
onDeactivated(() => scrollTop = mirrorRef.value.$el
    .getElementsByClassName('cm-scroller')[0].scrollTop)
onActivated(() => mirrorRef.value.$el.getElementsByClassName('cm-scroller')[0]
    .scrollTo({top: scrollTop}))

layout.value.mainLoading = true
request({
  url: '/platform/list',
  method: 'GET'
}).then(res => {
  platformList.value = res.data.data
  randomChat()
}).finally(() => layout.value.mainLoading = false)

document.onkeydown = function (e) {
  const ctrlKey = e.ctrlKey || e.metaKey
  if (ctrlKey && e.key.toLowerCase() === 's') {
    handleConfDialog('同步')
    e.preventDefault()
    return false
  }
}
</script>

<style lang="scss">
.config-panel {
  position: relative;
  flex: 1;
  margin: 1rem 0 1rem 1rem;
  overflow: hidden;
  display: flex;
  flex-direction: column;

  .el-tabs__content {
    position: static;
    flex: 1;
    padding: 1rem;
    overflow: hidden;

    .el-tab-pane {
      height: 100%;
      display: flex;
      flex-direction: column;
      overflow: hidden;
    }
  }
}

.fake-panel {
  flex-shrink: 0;
  width: 460px;
  margin: 1rem;
  background-color: var(--z-note-color);
  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, #555), color-stop(.25, transparent)),
  -webkit-gradient(linear, 0 0, 100% 100%, color-stop(.25, #555), color-stop(.25, transparent)),
  -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.75, transparent), color-stop(.75, #555)),
  -webkit-gradient(linear, 0 0, 100% 100%, color-stop(.75, transparent), color-stop(.75, #555));
  -webkit-background-size: 32px 32px;
  background-position: 0 0, 16px 0, 16px -16px, 0 16px;

  .el-card__body {
    position: relative;
    width: 100%;
    height: 100%;
    padding: 0;
  }
}

.btn-wrap {
  position: absolute;
  top: 0;
  right: 0;
  padding: 0 1rem;
  background: var(--z-light-color);
  height: 39px;
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>